import csv
import os
from cmath import log
from datetime import datetime, timedelta
from io import StringIO

import requests
from faiss import logger
from flask import Blueprint, jsonify, render_template, request, current_app, send_from_directory, Response
from flask_login import current_user
from sqlalchemy.testing.plugin.plugin_base import logging

from app import db
from app.function import get_city_code, GAODE_KEY, send_email
from app.iot_mqtt.iot_config import log_messages, HUAWEI_IOT_CONFIG
from app.iot_mqtt.iot_funciton import show_device_info, get_huawei_token, get_device_shadow
from app.models import Device, DeviceShadowData, User
from app.routes.cost import BASE_DIR

bp = Blueprint('iot', __name__)


@bp.route("/iot", methods=["GET"])
def iot_mqtt():
    """IoT 设备控制面板"""
    device_info = show_device_info()
    page = request.args.get('page', 1, type=int)
    per_page = 10
    device_id = request.args.get('device_id', device_info.get('device_id'))
    start_date = request.args.get('start_date', None)
    end_date = request.args.get('end_date', None)

    with current_app.app_context():
        devices = Device.query.all()
        device = Device.query.filter_by(id=device_id).first()
        if device:
            query = DeviceShadowData.query.filter_by(device_id=device.id)
            if start_date:
                query = query.filter(DeviceShadowData.timestamp >= start_date)
            if end_date:
                query = query.filter(DeviceShadowData.timestamp <= end_date)
            pagination = query.order_by(DeviceShadowData.timestamp.desc()).paginate(page=page, per_page=per_page,
                                                                                    error_out=False)
            shadow_data = pagination.items
            total_pages = pagination.pages
        else:
            current_app.logger.warning(f"设备 ID {device_id} 未找到")
            shadow_data = []
            total_pages = 1

        # 替换为实际日志查询，例如 DeviceActuatorLog
        # 示例：log_messages = [log.some_field for log in DeviceActuatorLog.query.order_by(DeviceActuatorLog.timestamp.desc()).limit(10).all()]

        return render_template("iot_mqtt.html",
                               device_info=device_info,
                               shadow_data=shadow_data,
                               logs=log_messages[-10:],
                               page=page,
                               total_pages=total_pages,
                               devices=devices,
                               selected_device=device_id,
                               start_date=start_date,
                               end_date=end_date,
                               current_time=datetime.now().strftime("%Y-%m-%d %H:%M:%S"))


# @bp.route("/device_info")
# def get_device_info():
#     """返回设备信息为 JSON"""
#     return jsonify(show_device_info())

@bp.route("/control/led", methods=["POST"])
def control_led():
    """控制LED"""
    state = request.json.get("state", False)
    return jsonify({"success": True, "led_state": state})


@bp.route('/control/remote', methods=['GET'])
def remote_control_page():
    try:
        return send_from_directory(os.path.join(BASE_DIR, 'templates'), 'cost.html')
    except Exception as e:
        logger.error(f"提供 cost.html 失败: {str(e)}")
        return jsonify({'error': '无法加载页面'}), 500


@bp.route('/control/rules')
def auto_rules_page():
    return render_template('control/rules.html')


@bp.route('/control/schedules')
def schedules_page():
    return render_template('control/job.html')


THRESHOLDS = {
    'temperature': {'max': 35.0, 'min': 10.0},
    'humidity': {'max': 80.0, 'min': 20.0},
    'light': {'max': 1000.0, 'min': 0.0},
    'soil': {'max': 90.0, 'min': 10.0},
    'rain': {'max': 50.0, 'min': 0.0},
    'uv': {'max': 10.0, 'min': 0.0},
    'co2': {'max': 2000, 'min': 0.0},
}


@bp.route("/device/info", methods=["GET"])
def get_device_info():
    """获取设备信息"""
    device_id = request.args.get('device_id')
    info = show_device_info(device_id)
    info['timestamp'] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    alerts = []
    if info['temperature'] > THRESHOLDS['temperature']['max'] or info['temperature'] < THRESHOLDS['temperature']['min']:
        alerts.append(
            f"温度 {info['temperature']}°C 超出范围 {THRESHOLDS['temperature']['min']}~{THRESHOLDS['temperature']['max']}°C")
    if info['humidity'] > THRESHOLDS['humidity']['max'] or info['humidity'] < THRESHOLDS['humidity']['min']:
        alerts.append(
            f"湿度 {info['humidity']}% 超出范围 {THRESHOLDS['humidity']['min']}~{THRESHOLDS['humidity']['max']}%")
    if info['light'] > THRESHOLDS['light']['max'] or info['light'] < THRESHOLDS['light']['min']:
        alerts.append(f"光照 {info['light']} 超出范围 {THRESHOLDS['light']['min']}~{THRESHOLDS['light']['max']}")
    if info['soil'] > THRESHOLDS['soil']['max'] or info['soil'] < THRESHOLDS['soil']['min']:
        alerts.append(f"土壤湿度 {info['soil']}% 超出范围 {THRESHOLDS['soil']['min']}~{THRESHOLDS['soil']['max']}%")
    if info['rain'] > THRESHOLDS['rain']['max'] or info['rain'] < THRESHOLDS['rain']['min']:
        alerts.append(f"降雨量 {info['rain']} 超出范围 {THRESHOLDS['rain']['min']}~{THRESHOLDS['rain']['max']}")
    if info['uv'] > THRESHOLDS['uv']['max'] or info['uv'] < THRESHOLDS['uv']['min']:
        alerts.append(f"紫外线指数 {info['uv']} 超出范围 {THRESHOLDS['uv']['min']}~{THRESHOLDS['uv']['max']}")
    if info['ph'] > THRESHOLDS['co2']['max'] or info['ph'] < THRESHOLDS['co2']['min']:
        alerts.append(f"pH值 {info['ph']} 超出范围 {THRESHOLDS['co2']['min']}~{THRESHOLDS['co2']['max']}")
    email = User.query.filter_by(id=current_user.id).first().email
    if not email:
        log("未找到用户邮箱")
    elif alerts:
        # 发送警报邮件
        subject = f"设备 {device_id} 数据异常警报"
        body = f"设备 {device_id} 检测到以下异常数据：\n\n" + "\n".join(alerts) + "\n\n请立即检查设备！"
        send_email(email, subject, body)
        logger.info(f"警报邮件已发送至 {email}")

    return jsonify(info)


@bp.route("/logs")
def get_logs():
    """获取日志"""
    return jsonify({"logs": log_messages[-20:]})


@bp.route("/dashboard")
def device_dashboard():
    """设备监控面板"""
    device_info = show_device_info()
    # return render_template("iot_dashboard.html",
    #                        device_info=device_info,
    #                        logs=log_messages[-10:])
    return render_template("iot_dashboard.html")


@bp.route('/weather')
def get_weather():
    """获取天气信息"""
    try:
        adcode = get_city_code()
        url = 'https://restapi.amap.com/v3/weather/weatherInfo'
        params = {
            'key': GAODE_KEY,
            'city': adcode,
            'extensions': 'base'
        }
        response = requests.get(url, params=params)
        weather_data = response.json()['lives'][0]

        # 格式化返回数据
        result = {
            'province': weather_data.get('province', ''),
            'city': weather_data.get('city', ''),
            'adcode': weather_data.get('adcode', ''),
            'weather': weather_data.get('weather', ''),
            'temperature': weather_data.get('temperature', ''),
            'winddirection': weather_data.get('winddirection', ''),
            'windpower': weather_data.get('windpower', ''),
            'humidity': weather_data.get('humidity', ''),
            'reporttime': weather_data.get('reporttime', '')
        }

        return jsonify(result)

    except Exception as e:
        return jsonify({'error': str(e)}), 500


@bp.route('/show_weather')
def get_show_weather():
    return render_template('weather.html')


@bp.route('/refresh_token')
def refresh_token():
    if get_huawei_token():
        return jsonify({'success': True})
    return jsonify({'success': False}), 500


@bp.route('/get_data')
def get_data():
    device_data = get_device_shadow() or {}
    return jsonify({
        'temperature': device_data.get('tem', device_data.get('Temp', '--')),
        'humidity': device_data.get('hum', device_data.get('Hum', '--')),
        'led_status': device_data.get('led', device_data.get('LED', False)),
        'stat_status': device_data.get('stat', False),
        'last_update': datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    })


@bp.route("/device/list", methods=["GET"])
def get_device_list():
    """获取所有设备列表"""
    with current_app.app_context():
        devices = Device.query.all()
        return jsonify({'devices': [{'id': device.id} for device in devices]})


@bp.route("/device/history", methods=["GET"])
def get_device_history():
    """获取设备历史数据"""
    device_id = request.args.get('device_id')
    range = request.args.get('range', '1h')
    with current_app.app_context():
        device = Device.query.filter_by(id=device_id).first()
        if not device:
            return jsonify({'error': '设备未找到'}), 404

        now = datetime.now()
        if range == '1h':
            start = now - timedelta(hours=1)
        elif range == '24h':
            start = now - timedelta(days=1)
        else:  # 7d
            start = now - timedelta(days=7)

        data = DeviceShadowData.query.filter_by(device_id=device.id).filter(
            DeviceShadowData.timestamp >= start
        ).order_by(DeviceShadowData.timestamp.asc()).all()

        return jsonify({
            'timestamps': [d.timestamp.strftime('%Y-%m-%d %H:%M:%S') for d in data],
            'temperature': [d.tem or 0.0 for d in data],
            'humidity': [d.hum or 0.0 for d in data],
            'light': [d.light or 0.0 for d in data],
            'uv': [d.uv or 0.0 for d in data],
            'ph': [d.co2 or 0.0 for d in data],
            'rain': [d.rain or 0.0 for d in data],
            'soil': [d.soil or 0.0 for d in data],
        })


@bp.route('/iot/export', methods=['GET'])
def export_iot_data():
    # 获取查询参数
    device_id = request.args.get('device_id')
    start_date = request.args.get('start_date')
    end_date = request.args.get('end_date')

    # 查询数据（替换为实际数据库查询）
    data = query_iot_data(device_id, start_date, end_date)

    # 创建CSV文件
    output = StringIO()
    writer = csv.writer(output, lineterminator='\n')

    # 写入表头
    headers = [
        '时间戳', '设备ID', '状态', '温度 (°C)', '湿度 (%)',
        '光照 (lx)', '土壤湿度 (%)', '雨水 (mm)', '紫外线',
        '土壤pH', 'LED状态', '风扇', '水泵'
    ]
    writer.writerow(headers)

    # 写入数据行
    for row in data:
        writer.writerow([
            row['timestamp'].strftime('%Y-%m-%d %H:%M:%S'),
            row['device_id'],
            '在线' if row['stat'] else '离线',
            row['tem'],
            row['hum'],
            row['light'],
            row['soil'],
            row['rain'],
            row['uv'],
            row['ph'],
            '开启' if row['led'] else '关闭',
            '开启' if row['fan'] else '关闭',
            '开启' if row['water'] else '关闭'
        ])

    # 设置响应头
    output.seek(0)
    timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
    filename = f'iot_data_{timestamp}.csv'
    return Response(
        output.getvalue(),
        mimetype='text/csv',
        headers={
            'Content-Disposition': f'attachment; filename={filename}',
            'Content-Type': 'text/csv; charset=utf-8'
        }
    )

def query_iot_data(device_id, start_date, end_date):
    query = DeviceShadowData.query

    # 应用设备ID筛选（如果提供）
    if device_id:
        query = query.filter(DeviceShadowData.device_id == device_id)

    # 应用时间范围筛选（如果提供）
    if start_date:
        try:
            start_date = datetime.strptime(start_date, '%Y-%m-%d')
            query = query.filter(DeviceShadowData.timestamp >= start_date)
        except ValueError:
            pass  # 忽略无效的日期格式

    if end_date:
        try:
            end_date = datetime.strptime(end_date, '%Y-%m-%d')
            # 包含当天的所有数据，调整为当天的23:59:59
            end_date = end_date.replace(hour=23, minute=59, second=59)
            query = query.filter(DeviceShadowData.timestamp <= end_date)
        except ValueError:
            pass  # 忽略无效的日期格式

    # 按时间戳降序排序
    query = query.order_by(DeviceShadowData.timestamp.desc())

    # 执行查询并获取结果
    results = query.all()

    # 转换结果为与前端表格匹配的字典列表
    data = [
        {
            'timestamp': record.timestamp,
            'device_id': record.device_id,
            'stat': record.stat,
            'tem': record.tem,
            'hum': record.hum,
            'light': record.light,
            'soil': record.soil,
            'rain': record.rain,
            'uv': record.uv,
            'ph': record.ph,
            'led': record.led,
            'fan': record.fan,
            'water': record.water
        }
        for record in results
    ]

    return data